/*
 * @Descripttion: 
 * @version: 
 * @Author: ldh
 * @Date: 2020-06-21 10:47:52
 * @LastEditors: ldh
 * @LastEditTime: 2020-07-05 17:25:09
 */ 
import config   from './config.js';    //配置文件
let _token = config['TOKEN'] || 'access_token'; //token字段
let _refresh_token = config['REFRESH_TOKEN'] || 'refresh_token'; //token字段

 function Http(){
    this.config = {
        baseUrl:'',
		dataType: "json",
		method:'GET',
        data:{},
    }
    this.requestQueue = [] // 请求队列
    this.isRefresh = false// 是否正在刷新token
    this.hasRefreshed = false // 是否刷新过token
    this.refreshTime = Date.now() // 刷新token 时间戳
    this.refreshExpire = 30000 // 重新刷新token 间隔
 }
 Http.prototype = {
     request(options){
         
        let contentType =''
        if(options.method && options.method.toLowerCase() === 'post'){
			contentType = 'application/json;charset=UTF-8'
        }else{
            contentType = 'application/x-www-form-urlencoded'
        }
        options = {
            token:true,
            ...this.config,
            ...options,
            header:{
                'Content-Type':contentType,
                ...options.header
            },
            url:this.config.baseUrl+options.url
        }
        return new Promise((resolve,reject)=>{
            options.fail = (err) =>{
                console.log(err,`！！！-${options.method}-请求失败的err`)
                this.deleteRequest(options.reqId)
				this.showToast(config['NETWORK_TIP'])
				reject(err)
            }// 请求成功
			options.success = (response) =>{
                console.log(response,`>>>-${options.method}-请求成功的response`)
                this.interResponse(response,resolve,reject)
            }
            this.interRequest(options,resolve,reject)
        })
     },
     uploaderFile(options){
        options = {
            ...options,
            header:{
                'Content-Type':'multipart/form-data',
                ...options.header,
            },
            url:this.config.baseUrl+options.url,
        }
        return new Promise((resolve,reject)=>{
			//请求失败
			options.fail = (err) => {
				console.log(err,`！！！-文件上传-请求失败的err`)
				this.showToast(config['NETWORK_TIP'])
				reject(err)
			}
			// 发送成功
			options.success = (response) => {
				console.log(response,`>>>-文件上传-请求成功的response`)
				this.interResponse(response,resolve,reject)
			}
            let token = wx.getStorageSync('userInfo')[_token] || ''
            if(!options.token || token){
                options.header[_token] = token
                wx.uploaderFile(options)
            }else{
                this.goLogin()
                reject({[config['MESSAGE']]:'请登录'});
            }
		})
     },
    interRequest(options,resolve,reject){
        
        let token = wx.getStorageSync('userInfo')[_token] || ''
        let refresh_token = wx.getStorageSync('userInfo')[_refresh_token] || ''
        if(!refresh_token){
            this.goLogin()
            return reject({[config['MESSAGE']]:'请登录'});
        }
        if(!options.token){
            return wx.request(options)
        }
        // 登录 或 刷新token 请求
        if(options.url.toLowerCase().indexOf('login')>=0){
            this.hasRefreshed = true
            return wx.request(options)
        }
        if(options.isRefreshToken){
            options.header[_refresh_token] = refresh_token
            return wx.request(options)
        }
        
       
        // 其他请求
        //刷新间隔到了 重新刷新token
        if(!this.isRefresh && Date.now() - this.refreshTime > this.refreshExpire){
            this.hasRefreshed = false
        }
        // 正在刷新token 期间 把请求 pending 状态 压入队列
        if(this.isRefresh){
            this.requestQueue.push(() => resolve(this.request(options)))
        }
        // 请求前 先刷新一次token 保证以后都用有效的token
        else if(!this.hasRefreshed){
            this.isRefresh = true
            this.requestQueue.push(()=> resolve(this.request(options)))
            this.handleRefresh()
        }
         else if(token){
            options.header[_token] = token
            wx.request(options)
        }else{
            console.log(options.token)
            this.goLogin()
            reject({[config['MESSAGE']]:'请登录'});
        }
        
    },
    interResponse(response,resolve,reject){
        let data = response.data;
        let statusCode = response.statusCode
        if(statusCode !== 200){
            reject(data)
        }else{
            switch (parseInt(data[config['STATUS']])) {
                case config['SUCCESS_CODE']:      // 正常返回
                    resolve(data)
                    break;
                default:      // 请求参数错误等
                    let message = data[config['MESSAGE']]
                    message && this.showToast(message)
                    resolve(data)
                    break;
            }
        }
    },
     goLogin(){
        wx.removeStorageSync('userInfo');
        this.showToast('请登录',()=>{
            wx.navigateTo({
                url:config['LOGIN_URL']
            })
        })
        setTimeout(() => {
            wx.setStorageSync('userInfo',{[_token]:'123',[_refresh_token]:'ddd'})
            wx.showToast({
                title:'模拟登录成功'
            })
        }, 2000);
     },
     showToast(title,mask){
        return new Promise((resolve)=>{
            wx.showToast({
                title: title,
                icon: "none",
                position: "bottom",
                mask: mask ||false,
                success:resolve
            })
        })
     },
     refreshToken(){
         return new Promise((resolve,reject)=>{
             // 用于模拟 刷新token的请求
             resolve(this.request({
                url:'http://api.douban.com/v2/movie/in_theaters',
                data:{
                    apikey:'0df993c66c0c636e29ecbb5344252a4a',
                    start:0,
                    count:10,
                },
                isRefreshToken:true // 用于标记该请求为刷新token
            }))
         })
     },
     handleRefresh(){
        console.log('refresh',this.requestQueue)
        this.refreshToken().then(res=>{
            console.log('refresh-over')
            // 存储 token
            wx.setStorageSync('userInfo',{[_token]:'12313',[_refresh_token]:'rtry'})
            this.isRefresh = false
            this.hasRefreshed = true
            this.refreshTime = Date.now()
            // 执行请求队列中请求
            this.requestQueue.forEach(req =>{
                req()
            })
            this.requestQueue.length = 0
        }).catch(err=>{
            // 刷新失败 清空请求队列 并登录
            this.requestQueue.length = 0
            this.goLogin()
        })
     }
 }

 export default new Http()